----------------------------------------------------------------------------------
-- Company:        EECS 452
-- Engineer:       Kurt Metzger
-- 
-- Create Date:    21:09:56 02/13/2007 
-- Design Name: 
-- Module Name:    McBSPXmtr - Behavioral 
-- Project Name: 
-- Target Devices: 
-- Tool versions: 
-- Description: 
--
-- Dependencies: 
--
-- Revision: 
-- Revision 0.01 - File Created
-- Revision 0.02 - rdy_in edge detection made more robust .. KM 12/06/2007
-- Additional Comments: 
--
--    Sends one 16-bit value per use.  Shift clock is
--    25 MHz.  Max value rate is approximately 1.5 MHz.
--    First attempt at moving data at high speed between
--    DSK McBSP0 and the FPGA.  Initial use was moving
--    single channel A/D 1 MHz 16-bit values.
--
----------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;

---- Uncomment the following library declaration if instantiating
---- any Xilinx primitives in this code.
--library UNISIM;
--use UNISIM.VComponents.all;

entity McBSPXmtr2 is
    Port (  data_send : in  STD_LOGIC_VECTOR (15 downto 0);
            data_rcvd : out  STD_LOGIC_VECTOR (15 downto 0);
            rdy_in : in  STD_LOGIC;
            ack_out : out  STD_LOGIC;
            pmod : inout  STD_LOGIC_VECTOR (3 downto 0);
            clk : in  STD_LOGIC;
            reset : in  STD_LOGIC);
end McBSPXmtr2;

architecture Behavioral of McBSPXmtr2 is

signal ctr : std_logic_vector(4 downto 0);
signal fsync : std_logic := '0';
signal sr_out : std_logic_vector(15 downto 0);
signal sr_in : std_logic_vector(15 downto 0);
signal data_r : std_logic_vector(15 downto 0);
signal input : std_logic;
signal ack : std_logic := '0';
signal sclk : std_logic;
type t_state is (s_idle, s_start0, s_start1);
signal state : t_state := s_idle;
signal rdy_in_old : std_logic;

begin

   pmod <= sclk & sr_out(15) & 'Z' & fsync;  -- pin 4, pin 3, pin2, pin1
   input <= pmod(1);
   ack_out <= ack;
   data_rcvd <= data_r;

   process(clk, rdy_in)
   begin
      if reset = '1' then
         fsync <= '0';
         ack <= '0';
         state <= s_idle;
      elsif rising_edge(clk) then
     
         if rdy_in = '0' then
            ack <= '0';
         end if;
			
			rdy_in_old <= rdy_in;
			sclk <= not sclk;
          
         case state is
            when s_idle =>
               --if (rdy_in_old & rdy_in) = "01" then
					if rdy_in = '1' then
					   sclk <= '1';
                  sr_out <= data_send;
                  data_r <= sr_in;
                  ack <= '1';
                  fsync <= '1';
                  ctr <= "00000";
                  state <= s_start0;
               end if;
				when s_start0 => -- on next - clock edge do
					if ctr = 16 then
						state <= s_idle;
					else
						state <= s_start1;
					end if;
            when s_start1 => -- on next + clock edge do
				   ctr <= ctr+1;
               fsync <= '0';
					sr_in <= sr_in(14 downto 0) & input;
					sr_out <= sr_out(14 downto 0) & '0';
               state <= s_start0;
         end case;
      end if;
   end process;
 
end Behavioral;

